#include "csynctcpsocket.h"
#include "const_define.h"
#include <QTextCodec>

#define MAX_ALIVE_SEC   100
#define BEAT_ALIVE_SEC  40

CSyncTcpSocket::CSyncTcpSocket(QObject *parent) :
    QTcpSocket(parent)
{
    _aes = NULL;
    _isGBK = false;
    _lastTimeRcv = QTime::currentTime();

    connect(&_aliveTimer,SIGNAL(timeout()),this,SLOT(doAlive()));
    connect(&_sendTimer,SIGNAL(timeout()),this,SLOT(doSendData()));

    _aliveTimer.start(5000);
}

void CSyncTcpSocket::readReadyData()
{
    _lastTimeRcv = QTime::currentTime();

    QString dmsg = this->readData();

    if(dmsg.length()>0)
    {
        QStringList list = dmsg.split(TCP_ALIVE_FALG);
        for(int i=0;i<list.size();i++)
        {
            QString msg = list.at(i);
            if(msg != TCP_ALIVE_FALG && !msg.trimmed().isEmpty())
                emit s_onceData(msg);
        }
    }
}

void CSyncTcpSocket::readyToWork()
{
    connect(this,SIGNAL(readyRead()),this,SLOT(readReadyData()));
}

bool CSyncTcpSocket::connectHostAndVerify(QString ip, int port, QString verifyMsg, QString ackMsg)
{
    this->connectToHost(ip,port);
    if(this->waitForConnected(2000))
    {
        this->sendData(verifyMsg);
        this->waitForReadyRead(3000);
        QString ack = this->readData().trimmed();
        if(!ack.isEmpty())
        {
            if(ack.startsWith(ackMsg))
            {
                this->readyToWork();
                return true;
            }
            else
            {
                qDebug() << "CSyncTcpSocket: connect fail with " << ack;
            }
        }else{
            qDebug() << "CSyncTcpSocket: connect but nothing get";
        }
    }

    return false;
}

void CSyncTcpSocket::doAlive()
{
    static QString aliveData(TCP_ALIVE_FALG);

    this->appendSendData(aliveData);

    if(_lastTimeRcv.secsTo(QTime::currentTime()) > MAX_ALIVE_SEC)
    {
        this->setSocketState(QTcpSocket::UnconnectedState);
        emit s_maybeDisconectFromHost();
    }
}

void CSyncTcpSocket::setSocketType(SockType type)
{
    sockType = type;
}

void CSyncTcpSocket::setEncryKey(QString key)
{
    _aes = new AESTools(&key);
}

void CSyncTcpSocket::sendData(QString msg)
{
    QString sendMsg;
    if(_aes)
        sendMsg = _aes->baseEncry(msg);
    else
        sendMsg = msg;

    this->write(sendMsg.toLocal8Bit());
    this->flush();
    this->waitForBytesWritten(50);
}

QString CSyncTcpSocket::readData()
{
    QByteArray dmsg;
    QByteArray msg = this->readAll().trimmed();
    if(msg == TCP_ALIVE_FALG)
    {
        return "";
    }

    if(_aes)
        dmsg = _aes->baseDecry(msg);
    else
    {
        dmsg = msg;
    }

    if(_isGBK){
        QTextCodec *gbk = QTextCodec::codecForName("gbk");
        QString unicode=gbk->toUnicode(dmsg);    //通过gbk编码对象将啊哈转为utf-16
        QTextCodec *utf8 = QTextCodec::codecForName("UTF-8");

            //QByteArray arr = utf8->fromUnicode(unicode); //从Unicode编码转为自身编码类型(utf-8)
        dmsg =  unicode.toUtf8();
    }

    return QString(dmsg);
}

void CSyncTcpSocket::doSendData()
{
    if(_sendList.size()>0)
    {
        QString smsg = _sendList.takeFirst();
        this->sendData(smsg);
    }
    else
    {
        _sendTimer.stop();
    }
}

bool CSyncTcpSocket::appendSendData(QString smsg)
{
    if(this->state() == QTcpSocket::ConnectedState || this->state() == QTcpSocket::ConnectingState)
    {
        _sendList.append(smsg);
        if(!_sendTimer.isActive())
            _sendTimer.start(100);

        return true;
    }
    else
        return false;
}

void CSyncTcpSocket::clearSendList()
{
    _sendList.clear();
}
